package com.yuliang.ai.logic;

import com.alibaba.fastjson.JSONObject;
import com.volcengine.ark.runtime.model.bot.completion.chat.BotChatCompletionRequest;
import com.volcengine.ark.runtime.model.bot.completion.chat.BotChatCompletionResult;
import com.volcengine.ark.runtime.model.completion.chat.ChatCompletionChoice;
import com.volcengine.ark.runtime.model.completion.chat.ChatMessage;
import com.volcengine.ark.runtime.model.completion.chat.ChatMessageRole;
import com.volcengine.ark.runtime.service.ArkService;
import com.yuliang.ai.domain.Dto.DouBaoBotChatVideoDto;
import com.yuliang.ai.domain.Vo.*;
import com.yuliang.ai.request.LoginUtils;
import com.yuliang.ai.request.RequestUrlUtils;
import com.yuliang.ai.sync.ThreadAsync;
import com.yuliang.ai.websocket.WebSocketServer;
import com.yuliang.utils.util.RedisUtils;
import com.yuliang.utils.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author Huangkai
 */
@Slf4j
@Component
public class AiOperation {

    @Value("${spring.chartGpt.baichuan.secret}")
    private String secret;

    @Value("${spring.chartGpt.baichuan.projectId}")
    private Integer projectId;

    @Value("${spring.login.username}")
    private String username;

    @Value("${spring.login.password}")
    private String password;

    @Value("${spring.chartGpt.doubao.botId}")
    private String botId;

    @Value("${spring.chartGpt.doubao.apiKey}")
    private String apiKey;

    @Autowired
    WebSocketServer messagePushWebSocket;

    @Autowired
    ThreadAsync threadAsync;

    public void qingBo(JSONObject jsonObject, String text){
        if(jsonObject.containsKey("username")){
            username = jsonObject.getString("username");
        }
        if(jsonObject.containsKey("password")){
            password = jsonObject.getString("password");
        }
        //设备id
        String deviceId = jsonObject.getString("deviceId");
        //用户id
        String userId = jsonObject.getString("userId");
        String humanIdentifyId = jsonObject.getString("humanIdentifyId");
        //登陆
        LoginUtils.loginOperation(username, password);
        ChatVo chatVo = new ChatVo();
        chatVo.setChatId(0);
        chatVo.setSecret(secret);
        chatVo.setProjectId(projectId);
        //projectId是否存在
        if(jsonObject.containsKey("projectId")){
            chatVo.setProjectId(jsonObject.getInteger("projectId"));
        }
        //token是否存在
        if(jsonObject.containsKey("token")){
            chatVo.setSecret(jsonObject.getString("token"));
        }
        //设置的key
        String connectionKey = deviceId + userId + humanIdentifyId;
        //判断是否为五分钟会话一次
        if (RedisUtils.hasKey(connectionKey)) {
            MessageVo messageVo = JSONObject.parseObject(RedisUtils.get(connectionKey), MessageVo.class);
            chatVo.setChatId(messageVo.getChatId());
        }
        chatVo.setUserId(userId);
        chatVo.setHumanIdentifyId(humanIdentifyId);
        chatVo.setDeviceId(deviceId);
        chatVo.setTitle(text);
        RequestUrlUtils.request(chatVo);
    }

    /**
     * 豆包大模型
     * @param chatDoubaoVo
     * @return
     */
    public void douBaoBotChatCompletions(ChatDoubaoVo chatDoubaoVo) {
        StopWatch sw = new StopWatch();
        String chatKeyLock = chatDoubaoVo.getDeviceId() + chatDoubaoVo.getUserId() + chatDoubaoVo.getHumanIdentifyId() + "lock";
        RedisUtils.setEx(chatKeyLock, (chatDoubaoVo.getChatId() + chatDoubaoVo.getChatAnsId() +""), 1, TimeUnit.MINUTES);
        sw.start();
        StringBuffer allContent = new StringBuffer();
        //保存上下文的key
        String historyContextKey = chatDoubaoVo.getUserId() + chatDoubaoVo.getHumanIdentifyId() + chatDoubaoVo.getDeviceId();
        String limitWord = "请用%s字以内回答以下内容：";
        log.info("执行豆包大模型。。。{}", chatDoubaoVo);
        List<String> videoPathList = new ArrayList<>();
        List<String> imgList = new ArrayList<>();
        ArkService service = new ArkService(apiKey);
        List<ChatMessage> streamMessages = new ArrayList<>();
        ChatMessage streamSystemMessage = ChatMessage.builder().role(ChatMessageRole.SYSTEM).content("你是一个资深数字导游，你叫刘三姐AI旅游助手，是由广旅集团开发的AI。").build();
        String prompt = String.format(limitWord, chatDoubaoVo.getWordLimit());
        if(RedisUtils.hasKey(historyContextKey)){
            Map<Object, Object> hGetAll = RedisUtils.hGetAll(historyContextKey);
            hGetAll.forEach((key, value) ->{
                //历史的提问
                ChatMessage historyUserMessage = ChatMessage.builder().role(ChatMessageRole.USER).content(key.toString()).build();
                streamMessages.add(historyUserMessage);
                //历史结果
                ChatMessage historyAssistantMessage = ChatMessage.builder().role(ChatMessageRole.ASSISTANT).content(value.toString()).build();
                streamMessages.add(historyAssistantMessage);
            });
        }

        String submitContent = prompt + chatDoubaoVo.getTitle();
        ChatMessage streamUserMessage = ChatMessage.builder().role(ChatMessageRole.USER).content(submitContent).build();
        streamMessages.add(streamSystemMessage);
        streamMessages.add(streamUserMessage);
        JSONObject resultJSON = new JSONObject();
        resultJSON.put("type", 0);
        resultJSON.put("chatId", chatDoubaoVo.getChatId());
        BotChatCompletionRequest streamChatCompletionRequest = BotChatCompletionRequest.builder()
                .model("Doubao-pro-32k")
                .botId(botId)
                .messages(streamMessages)
                .maxTokens(240)
                .build();
        service.streamBotChatCompletion(streamChatCompletionRequest)
                .doOnError(Throwable::printStackTrace)
                .blockingForEach(
                        choice -> {
                            String dooubaoChartAndId = choice.getId();
                            resultJSON.put("chatAnsId", chatDoubaoVo.getChatAnsId());
                            List<ChatCompletionChoice>  chatCompletionChoiceList = choice.getChoices();
                            if(!chatCompletionChoiceList.isEmpty()){
                                for(ChatCompletionChoice chatCompletionChoice : chatCompletionChoiceList){
                                    log.info("内容{}", JSONObject.toJSONString(chatCompletionChoice));
                                    String content = chatCompletionChoice.getMessage().getContent().toString();
                                    allContent.append(content);
                                    if(StringUtils.isNotEmpty(chatCompletionChoice.getFinishReason()) && chatCompletionChoice.getFinishReason().equals("isEnd")){
                                        resultJSON.put("videoPathList", videoPathList);
                                        resultJSON.put("imgList", imgList);
                                    }
                                }
                            }
                        }
                );
        String connectionKey = chatDoubaoVo.getDeviceId() + chatDoubaoVo.getUserId() + chatDoubaoVo.getHumanIdentifyId();
        if(RedisUtils.hasKey(connectionKey)){
            String requestId = RedisUtils.get(connectionKey);
            if(requestId.equals(chatDoubaoVo.getRequestId())){
                RedisUtils.delete(connectionKey);
                return;
            }
        }
        threadAsync.asyncWebsocket(resultJSON, chatDoubaoVo, allContent.toString(), chatKeyLock);
        sw.stop();
        log.debug("请求接口总耗时：{}秒",sw.getTotalTimeSeconds());
        service.shutdownExecutor();
    }

    public String douBaoBotChatVideo(ChatDoubaoVo chatDoubaoVo){
        ArkService service = new ArkService(apiKey);
        List<ChatMessage> messages = new ArrayList<>();
        ChatMessage systemMessage = ChatMessage.builder().role(ChatMessageRole.SYSTEM).content("你是一个资深数字导游，你叫刘三姐AI旅游助手，是由广旅集团开发的AI。").build();
        ChatMessage userMessage = ChatMessage.builder().role(ChatMessageRole.USER).content(chatDoubaoVo.getTitle()).build();
        messages.add(systemMessage);
        messages.add(userMessage);

        BotChatCompletionRequest chatCompletionRequest = BotChatCompletionRequest.builder()
                .model("Doubao-pro-32k")
                .botId(botId)
                .messages(messages)
                .build();

        BotChatCompletionResult chatCompletionResult =  service.createBotChatCompletion(chatCompletionRequest);
        log.info("返回的值{}", JSONObject.toJSONString(chatCompletionResult));
        DouBaoBotChatVideoDto baoBotChatVideoDto = new DouBaoBotChatVideoDto();

        chatCompletionResult.getChoices().forEach(
                choice -> System.out.println(choice.getMessage().getContent())
        );
        // the references example
        chatCompletionResult.getReferences().forEach(
                ref -> System.out.println(ref.getUrl())
        );
        return null;
    }

    /**
     * 实体类转换
     * @param jsonObject
     * @param text
     * @return
     */
    public ChatDoubaoVo buildChatDoubaoVo(JSONObject jsonObject, String text){
        ChatDoubaoVo chatDoubaoVo = new ChatDoubaoVo();
        chatDoubaoVo.setTitle(text);
        chatDoubaoVo.setChatId(0);
        chatDoubaoVo.setChatAnsId((int)(Math.random() * 1000  + 1));
        chatDoubaoVo.setApiKey(apiKey);
        chatDoubaoVo.setBotId(botId);
        if(jsonObject.containsKey("wordLimit")){
            chatDoubaoVo.setWordLimit(jsonObject.getInteger("wordLimit"));
        }
        if(jsonObject.containsKey("requestId")){
            chatDoubaoVo.setRequestId(jsonObject.getString("requestId"));
        }
        chatDoubaoVo.setDeviceId(jsonObject.getString("deviceId"));
        chatDoubaoVo.setHumanIdentifyId(jsonObject.getString("humanIdentifyId"));
        chatDoubaoVo.setUserId(jsonObject.getString("userId"));
        return chatDoubaoVo;
    }

}
